package com.jwds.digital.bios.business.service.service.belt.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jwds.digital.bios.business.core.infrastructure.entity.belt.BeltAnomalyInfo;
import com.jwds.digital.bios.business.core.infrastructure.vo.belt.BeltMonthlyAverageScoreVO;
import com.jwds.digital.bios.business.service.service.belt.IBeltAnomalyInfoService;
import com.jwds.digital.bios.business.service.service.belt.IBeltHealthMonthService;
import com.jwds.digital.bios.business.core.infrastructure.dto.belt.BeltHealthMonthReqDTO;
import com.jwds.digital.bios.business.core.infrastructure.vo.belt.BeltHealthMonthRespVO;
import com.jwds.digital.bios.business.core.infrastructure.dto.belt.assembler.BeltHealthMonthAssembler;
import com.jwds.digital.bios.business.core.infrastructure.entity.belt.BeltHealthMonth;
import com.jwds.digital.bios.business.core.infrastructure.mapper.belt.BeltHealthMonthMapper;
import com.jwds.digital.bios.business.core.exceptions.RecordNotFoundException;
import com.jwds.digital.bios.business.service.service.belt.IBeltHealthScoreDayService;
import com.jwds.tdc.framework.application.lib.page.PageRequest;
import com.jwds.tdc.framework.application.lib.page.PageResponse;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 皮带健康数据汇总-月实现类
 * @author 林柏云
 * @date 2024-10-24
 */
@Slf4j
@Service
public class BeltHealthMonthServiceImpl extends ServiceImpl<BeltHealthMonthMapper, BeltHealthMonth> implements IBeltHealthMonthService {

  @Autowired
  private BeltHealthMonthMapper baseMapper;

  @Resource
  private IBeltHealthScoreDayService beltHealthScoreDayService;

  @Resource
  private IBeltAnomalyInfoService beltAnomalyInfoService;

  @Override
  public BeltHealthMonthRespVO queryById(Long id) {
    if(id == null) {
      return null;
    }
    BeltHealthMonth entity = baseMapper.selectById(id);
    return BeltHealthMonthAssembler.entity2dto(entity);
  }

  @Override
  public PageResponse<BeltHealthMonthRespVO> page(PageRequest<BeltHealthMonthReqDTO> request) {
    BeltHealthMonthReqDTO condition = request.getQueryCondition();
    Page<BeltHealthMonthRespVO> page = new Page<>(request.getPageIndex(), request.getPageSize());
    IPage<BeltHealthMonthRespVO> pageData = baseMapper.pageQuery(page, condition);
    return new PageResponse<>((Page<?>)pageData, pageData.getRecords());
  }

  @Override
  public List<BeltHealthMonthRespVO> list(BeltHealthMonthReqDTO reqDto) {
    return baseMapper.queryList(reqDto);
  }

  @Override
  public void add(BeltHealthMonthReqDTO reqDto) {
    BeltHealthMonth entity = BeltHealthMonthAssembler.dto2entity(reqDto);
    baseMapper.insert(entity);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void batchAdd(List<BeltHealthMonthReqDTO> dtoList) {
    dtoList.forEach(this::add);
  }

  @Override
  public void update(BeltHealthMonthReqDTO reqDto) {
    BeltHealthMonth oldEntity = baseMapper.selectById(reqDto.getId());
    if (oldEntity == null) {
      throw new RecordNotFoundException();
    }
    BeltHealthMonth newEntity = BeltHealthMonthAssembler.dto2entity(reqDto, oldEntity);
    baseMapper.updateById(newEntity);
  }

  @Override
  public void delete(Long id) {
    BeltHealthMonth oldEntity = baseMapper.selectById(id);
    if (oldEntity == null) {
      throw new RecordNotFoundException();
    }
    baseMapper.deleteById(id);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void batchDelete(List<Long> ids) {
    for (Long id : ids) {
      delete(id);
    }
  }

  @Override
  public BeltHealthMonthRespVO analyze(BeltHealthMonthReqDTO reqDto) {
    Long id=reqDto.getId();
    String beltName=reqDto.getBeltName();
    // 从belt_health_score_day中查询健康、机械、五防分数
    Integer mechanicalScore=beltHealthScoreDayService.todayMechanicalScore(id);
    Integer fiveDefenseScore=beltHealthScoreDayService.todayFiveDefenseScore(id);
    Integer healthScore=beltHealthScoreDayService.todayHealthScore(id);
    // 从belt_anomaly_info中查询1月异常项
    List<BeltAnomalyInfo> anomalys=beltAnomalyInfoService.monthAnomalyItem(id);
    // 查询健康数据汇总
    LocalDateTime todayStart = LocalDate.now().atStartOfDay();
    // 查询这7月的数据健康数据汇总
    List<BeltHealthMonth> beltHealthDayList= this.list(new LambdaQueryWrapper<BeltHealthMonth>().eq(BeltHealthMonth::getBeltName, beltName)
            .between(BeltHealthMonth::getDate, todayStart.minusDays(30*7), todayStart).orderByAsc(BeltHealthMonth::getDate));
    // 本月开始的时间
    LocalDateTime todayStartMonth = todayStart.withDayOfMonth(1);
    LocalDateTime todayEndMonth = todayStartMonth.plusMonths(1).minusDays(1);
    // 查询本月的数据
    BeltHealthMonth beltHealthWeek= baseMapper.analyze(beltName, todayStartMonth, todayEndMonth);
    //如果beltHealthDay为空
    if(beltHealthWeek==null){
      beltHealthWeek= baseMapper.analyze(beltName, todayStartMonth.minusMonths(1), todayEndMonth.minusMonths(1));
      beltHealthWeek= Optional.ofNullable(beltHealthWeek).orElse(new BeltHealthMonth());
    }

    // 计算出近12个月，每个月的平均机械分数、健康分数、五防分数
    List<BeltMonthlyAverageScoreVO> beltMonthlyAverageScoreVOList= beltHealthScoreDayService.monthlyAverageScore(id,todayStart);
    // 封装返回数据
    BeltHealthMonthRespVO respVo = new BeltHealthMonthRespVO();
    beltHealthWeek= Optional.ofNullable(beltHealthWeek).orElse(new BeltHealthMonth());
    BeanUtils.copyProperties(beltHealthWeek, respVo);
    respVo.setBeltMonthlyAverageScoreVOList(beltMonthlyAverageScoreVOList);
    respVo.setMechanicalScore(mechanicalScore);
    respVo.setFiveDefenseScore(fiveDefenseScore);
    respVo.setHealthScore(healthScore);
    respVo.setAnomalys(anomalys);
    respVo.setBeltHealthDayList(beltHealthDayList);
    respVo.setDeviceMark("直接启动/通用");
    respVo.setDeviceModel("三相异步电机/YE2E2-315-4");
    respVo.setDeviceName("皮带机/通用");
    respVo.setAverageScore((mechanicalScore+fiveDefenseScore+healthScore)/3.0);
    return respVo;
  }

}